Uso de listas y dataframes en R

En este taller veremos el uso de listas y dataframes en R. Ambos tipos de objetos son bastante usados en el análisis de datos en R.


In [1]:
Sys.setlocale("LC_ALL", 'en_US.UTF-8')


'en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8'

Uso de variables tipo matriz

Las variables tipo escalar y vector son útiles a la hora de analizar situaciones con pocos datos. Como iremos viendo a lo largo del curso, la mayoría de los proyectos de análsis de datos requieren usar bases de datos o tablas que contienen múltiples columnas y filas. Una manera de manipular este tipo de datos es usando matrices.


In [2]:
region = c("Arica y Parinacota","Tarapacá","Antofagasta","Atacama","Coquimbo","Valparaíso","Metropolitana de Santiago","Libertador General Bernardo O'Higgins","Maule","Biobío","La Araucanía","Los Ríos","Los Lagos","Aisén del General Carlos Ibáñez del Campo","Magallanes y de la Antártica Chilena")
poblacion = c(308271,205566,551627,292054,714856,1859312,7150480,903248,1073635,2025995,933537,380618,835829,106893,158828)
superficie = c(17446.20,41632.60,126048.80,74806.30,40967.80,12646.28,15547.00,16583.30,30340.30,37068.70,31842.30,18577.60,48583.30,107449.40,1392783.70)

In [3]:
class(region)
class(poblacion)
class(superficie)


'character'
'numeric'
'numeric'

In [4]:
chile = matrix(c(poblacion,superficie), ncol=2, byrow=FALSE)
chile


308271 17446.20
205566 41632.60
551627 126048.80
292054 74806.30
714856 40967.80
1859312 12646.28
7150480 15547.00
903248 16583.30
1073635 30340.30
2025995 37068.70
933537 31842.30
380618 18577.60
835829 48583.30
106893 107449.40
158828 1392783.70

In [5]:
class(chile)


'matrix'

In [6]:
colnames(chile)=c("poblacion","superficie")
rownames(chile)=region
chile


poblacionsuperficie
Arica y Parinacota 308271 17446.20
Tarapacá 205566 41632.60
Antofagasta 551627 126048.80
Atacama 292054 74806.30
Coquimbo 714856 40967.80
Valparaíso1859312 12646.28
Metropolitana de Santiago7150480 15547.00
Libertador General Bernardo O'Higgins 903248 16583.30
Maule1073635 30340.30
Biobío2025995 37068.70
La Araucanía 933537 31842.30
Los Ríos 380618 18577.60
Los Lagos 835829 48583.30
Aisén del General Carlos Ibáñez del Campo 106893 107449.40
Magallanes y de la Antártica Chilena 158828 1392783.70

Una vez que los datos están ordenados en forma matricial, es mucho más fácil responder preguntas tales como

  • ¿Cuáles son las regiones con mayor población?
  • ¿Cuáles son las regiones más pequeñas en superficie?
  • ¿Cuáles son las regiones con la mayor densidad de población por $km^2$?

In [7]:
chile[order(chile[,"poblacion"],decreasing=TRUE),]


poblacionsuperficie
Metropolitana de Santiago7150480 15547.00
Biobío2025995 37068.70
Valparaíso1859312 12646.28
Maule1073635 30340.30
La Araucanía 933537 31842.30
Libertador General Bernardo O'Higgins 903248 16583.30
Los Lagos 835829 48583.30
Coquimbo 714856 40967.80
Antofagasta 551627 126048.80
Los Ríos 380618 18577.60
Arica y Parinacota 308271 17446.20
Atacama 292054 74806.30
Tarapacá 205566 41632.60
Magallanes y de la Antártica Chilena 158828 1392783.70
Aisén del General Carlos Ibáñez del Campo 106893 107449.40

In [8]:
chile[order(chile[,"superficie"],decreasing=FALSE),]


poblacionsuperficie
Valparaíso1859312 12646.28
Metropolitana de Santiago7150480 15547.00
Libertador General Bernardo O'Higgins 903248 16583.30
Arica y Parinacota 308271 17446.20
Los Ríos 380618 18577.60
Maule1073635 30340.30
La Araucanía 933537 31842.30
Biobío2025995 37068.70
Coquimbo 714856 40967.80
Tarapacá 205566 41632.60
Los Lagos 835829 48583.30
Atacama 292054 74806.30
Aisén del General Carlos Ibáñez del Campo 106893 107449.40
Antofagasta 551627 126048.80
Magallanes y de la Antártica Chilena 158828 1392783.70

La densidad de población se define como el número de personas por unidad de superficie. En nuestro caso, sería simplemente dividir la columna poblacion por superficie.


In [9]:
chile[,'poblacion']/chile[,'superficie']


Arica y Parinacota
17.6698077518313
Tarapacá
4.93762099892872
Antofagasta
4.37629711667227
Atacama
3.90413641631788
Coquimbo
17.4492162137093
Valparaíso
147.024421410881
Metropolitana de Santiago
459.92667395639
Libertador General Bernardo O'Higgins
54.4673255624634
Maule
35.3864332257756
Biobío
54.65514032054
La Araucanía
29.3175116119125
Los Ríos
20.4880070622685
Los Lagos
17.2040392480544
Aisén del General Carlos Ibáñez del Campo
0.994821748655646
Magallanes y de la Antártica Chilena
0.114036371907569

In [10]:
densidad = poblacion/superficie
densidad


  1. 17.6698077518313
  2. 4.93762099892872
  3. 4.37629711667227
  4. 3.90413641631788
  5. 17.4492162137093
  6. 147.024421410881
  7. 459.92667395639
  8. 54.4673255624634
  9. 35.3864332257756
  10. 54.65514032054
  11. 29.3175116119125
  12. 20.4880070622685
  13. 17.2040392480544
  14. 0.994821748655646
  15. 0.114036371907569

Para agregar columnas a una matriz usaremos la función cbind()


In [11]:
chile <- cbind(chile, densidad)
chile


poblacionsuperficiedensidad
Arica y Parinacota 308271 17446.20 17.6698078
Tarapacá 205566 41632.60 4.9376210
Antofagasta 551627 126048.80 4.3762971
Atacama 292054 74806.30 3.9041364
Coquimbo 714856 40967.80 17.4492162
Valparaíso1859312 12646.28 147.0244214
Metropolitana de Santiago7150480 15547.00 459.9266740
Libertador General Bernardo O'Higgins 903248 16583.30 54.4673256
Maule1073635 30340.30 35.3864332
Biobío2025995 37068.70 54.6551403
La Araucanía 933537 31842.30 29.3175116
Los Ríos 380618 18577.60 20.4880071
Los Lagos 835829 48583.30 17.2040392
Aisén del General Carlos Ibáñez del Campo 106893 107449.40 0.9948217
Magallanes y de la Antártica Chilena 158828 1392783.70 0.1140364

¿Qué sucede si queremos agregar una nueva columna que tiene datos mixtos, digamos numéricos y caractéres?


In [12]:
codigo_region <- c("XV","I","II","III","IV","V","XIII","VI","VII","VIII","IX","XIV","X","XI","XII")
class(codigo_region)


'character'

In [13]:
chile <- cbind(chile, codigo_region)
chile


poblacionsuperficiedensidadcodigo_region
Arica y Parinacota308271 17446.2 17.6698077518313 XV
Tarapacá205566 41632.6 4.93762099892872 I
Antofagasta551627 126048.8 4.37629711667227 II
Atacama292054 74806.3 3.90413641631788 III
Coquimbo714856 40967.8 17.4492162137093 IV
Valparaíso1859312 12646.28 147.024421410881 V
Metropolitana de Santiago7150480 15547 459.92667395639 XIII
Libertador General Bernardo O'Higgins903248 16583.3 54.4673255624634 VI
Maule1073635 30340.3 35.3864332257756 VII
Biobío2025995 37068.7 54.65514032054 VIII
La Araucanía933537 31842.3 29.3175116119125 IX
Los Ríos380618 18577.6 20.4880070622685 XIV
Los Lagos835829 48583.3 17.2040392480544 X
Aisén del General Carlos Ibáñez del Campo106893 107449.4 0.994821748655646XI
Magallanes y de la Antártica Chilena158828 1392783.7 0.114036371907569XII

In [14]:
class(chile)


'matrix'

¿Que tal si queremos volver a calcular la densidad de población usando las columnas poblacion y superficie?


In [15]:
chile[,'poblacion']/chile[,'superficie']


Error in chile[, "poblacion"]/chile[, "superficie"]: non-numeric argument to binary operator
Traceback:

¿Porqué falló la división si antes funcionaba? ¿Habrá sido porque incluimos la columna codigo_region la cual contenia tipos de datos mixtos?

Partamos imprimiendo los tipos de clase de las columnas poblacion y superficie


In [16]:
class(chile[,'poblacion'])
class(chile[,'superficie'])


'character'
'character'

¿Qué sucedió?

La columna codigo_region es un vector que contiene datos de tipo caracter, y al ser incluida a la matriz todos los datos fueron convertidos al tipo de datos más general entre los tipos númerico y caracter: caracter.

Aquí vemos una gran limitación del tipo de datos matriz: No puede almacenar tipos de datos mixtos.

Uso de listas

Una lista es un vector genérico que puede contener otro tipo de objectos. Una lista puede contener escalares, caracterés, vectores numéricos, etc.


In [17]:
region <- c("Arica y Parinacota","Tarapacá","Antofagasta")
poblacion <- c(308271,205566,551627)
superficie <- c(17446.20,41632.60,126048.80)
codigo_region <- c("XV","I","II")

# Podemos definir los labels de los elements usando names
chile = list(region, poblacion, superficie, codigo_region)
names(chile) = c("region","poblacion","superficie","codigo_region")
chile

# O directamente al momento de definir la lista
chile = list(region=region, poblacion=poblacion, superficie=superficie, codigo_region=codigo_region)
chile


$region
  1. 'Arica y Parinacota'
  2. 'Tarapacá'
  3. 'Antofagasta'
$poblacion
  1. 308271
  2. 205566
  3. 551627
$superficie
  1. 17446.2
  2. 41632.6
  3. 126048.8
$codigo_region
  1. 'XV'
  2. 'I'
  3. 'II'
$region
  1. 'Arica y Parinacota'
  2. 'Tarapacá'
  3. 'Antofagasta'
$poblacion
  1. 308271
  2. 205566
  3. 551627
$superficie
  1. 17446.2
  2. 41632.6
  3. 126048.8
$codigo_region
  1. 'XV'
  2. 'I'
  3. 'II'

In [18]:
chile["region"]


$region =
  1. 'Arica y Parinacota'
  2. 'Tarapacá'
  3. 'Antofagasta'

In [19]:
chile[c("region","poblacion")]


$region
  1. 'Arica y Parinacota'
  2. 'Tarapacá'
  3. 'Antofagasta'
$poblacion
  1. 308271
  2. 205566
  3. 551627

¿Que tal si queremos calcular la densidad de población?


In [20]:
chile["poblacion"]/chile["superficie"]


Error in chile["poblacion"]/chile["superficie"]: non-numeric argument to binary operator
Traceback:

La razón por la cual falla es porque chile[2] sigue siendo una lista, y nosotros en verdad queremos acceder directamente al vector numérico. Para ello usamos llave cuadrada doble [[]] .


In [21]:
chile[["poblacion"]]/chile[["superficie"]]


  1. 17.6698077518313
  2. 4.93762099892872
  3. 4.37629711667227

Como podemos ver, las listas son un tipo de objeto que puede contener diferentes tipos de datos. A lo largo del curso iremos viendo situaciones donde las lostas son muy convenientes para almacenar datos.

Uso de DataFrames

Un dataframe es una estructura 2-dimensional que comparte propiedades entre una lista y una matriz. En estricto rigor, se define como una lista de vectores de igual largo.

Al igual que una lista y una matriz, un dataframe tiene las propiedades names(), colnames() y rownames(). En el caso del dataframe,

  • Las funciones names() y colnames() son equivalentes, y asignam los nombres de las columnas
  • La función rownames() asigna los nombres de las filas
  • Las funciones length() y ncol() son equivalentes, y entregan el número de columnas
  • La propiedad nrow()entrega el número de filas

In [22]:
region <- c("Arica y Parinacota","Tarapacá","Antofagasta")
poblacion <- c(308271,205566,551627)
superficie <- c(17446.20,41632.60,126048.80)
codigo_region <- c("XV","I","II")

chile <- data.frame(poblacion, superficie, codigo_region)
colnames(chile) <- c("poblacion","superficie","codigo_region")
rownames(chile) <- region
chile


poblacionsuperficiecodigo_region
Arica y Parinacota308271 17446.2XV
Tarapacá205566 41632.6I
Antofagasta551627 126048.8II

In [23]:
chile["poblacion"]


poblacion
Arica y Parinacota308271
Tarapacá205566
Antofagasta551627

In [24]:
chile["densidad"] <- chile["poblacion"]/chile["superficie"]
chile


poblacionsuperficiecodigo_regiondensidad
Arica y Parinacota308271 17446.2 XV 17.669808
Tarapacá205566 41632.6 I 4.937621
Antofagasta551627 126048.8 II 4.376297

In [25]:
region = c("Arica y Parinacota","Tarapacá","Antofagasta","Atacama","Coquimbo","Valparaíso","Metropolitana de Santiago","Libertador General Bernardo O'Higgins","Maule","Biobío","La Araucanía","Los Ríos","Los Lagos","Aisén del General Carlos Ibáñez del Campo","Magallanes y de la Antártica Chilena")
poblacion = c(308271,205566,551627,292054,714856,1859312,7150480,903248,1073635,2025995,933537,380618,835829,106893,158828)
superficie = c(17446.20,41632.60,126048.80,74806.30,40967.80,12646.28,15547.00,16583.30,30340.30,37068.70,31842.30,18577.60,48583.30,107449.40,1392783.70)
codigo_region <- c("XV","I","II","III","IV","V","XIII","VI","VII","VIII","IX","XIV","X","XI","XII")

chile <- data.frame(poblacion, superficie, codigo_region)
colnames(chile) <- c("poblacion","superficie","codigo_region")
rownames(chile) <- region
chile


poblacionsuperficiecodigo_region
Arica y Parinacota 308271 17446.20XV
Tarapacá 205566 41632.60I
Antofagasta 551627 126048.80II
Atacama 292054 74806.30III
Coquimbo 714856 40967.80IV
Valparaíso1859312 12646.28V
Metropolitana de Santiago7150480 15547.00XIII
Libertador General Bernardo O'Higgins 903248 16583.30VI
Maule1073635 30340.30VII
Biobío2025995 37068.70VIII
La Araucanía 933537 31842.30IX
Los Ríos 380618 18577.60XIV
Los Lagos 835829 48583.30X
Aisén del General Carlos Ibáñez del Campo 106893 107449.40XI
Magallanes y de la Antártica Chilena 158828 1392783.70XII

Ordenar los datos del dataframe usando una columna


In [26]:
chile[order(poblacion),]


poblacionsuperficiecodigo_region
Aisén del General Carlos Ibáñez del Campo 106893 107449.40XI
Magallanes y de la Antártica Chilena 158828 1392783.70XII
Tarapacá 205566 41632.60I
Atacama 292054 74806.30III
Arica y Parinacota 308271 17446.20XV
Los Ríos 380618 18577.60XIV
Antofagasta 551627 126048.80II
Coquimbo 714856 40967.80IV
Los Lagos 835829 48583.30X
Libertador General Bernardo O'Higgins 903248 16583.30VI
La Araucanía 933537 31842.30IX
Maule1073635 30340.30VII
Valparaíso1859312 12646.28V
Biobío2025995 37068.70VIII
Metropolitana de Santiago7150480 15547.00XIII

In [27]:
chile[order(-poblacion),]


poblacionsuperficiecodigo_region
Metropolitana de Santiago7150480 15547.00XIII
Biobío2025995 37068.70VIII
Valparaíso1859312 12646.28V
Maule1073635 30340.30VII
La Araucanía 933537 31842.30IX
Libertador General Bernardo O'Higgins 903248 16583.30VI
Los Lagos 835829 48583.30X
Coquimbo 714856 40967.80IV
Antofagasta 551627 126048.80II
Los Ríos 380618 18577.60XIV
Arica y Parinacota 308271 17446.20XV
Atacama 292054 74806.30III
Tarapacá 205566 41632.60I
Magallanes y de la Antártica Chilena 158828 1392783.70XII
Aisén del General Carlos Ibáñez del Campo 106893 107449.40XI

Calcular promedios de columnas


In [28]:
colMeans(chile["poblacion"])


poblacion: 1166716.6

In [29]:
colMeans(chile[1:2])


poblacion
1166716.6
superficie
134154.905333333

Otra manera de calcular el promedio es usar la función apply()


In [30]:
apply(chile["poblacion"], 2, mean)


poblacion: 1166716.6

In [31]:
apply(chile["poblacion"], 2, sd)


poblacion: 1753174.97922462

In [32]:
apply(chile["poblacion"], 2, sum)


poblacion: 17500749

Obtener un resumen del dataframe


In [33]:
summary(chile)


   poblacion         superficie      codigo_region
 Min.   : 106893   Min.   :  12646   I      :1    
 1st Qu.: 300162   1st Qu.:  18012   II     :1    
 Median : 714856   Median :  37069   III    :1    
 Mean   :1166717   Mean   : 134155   IV     :1    
 3rd Qu.:1003586   3rd Qu.:  61695   IX     :1    
 Max.   :7150480   Max.   :1392784   V      :1    
                                     (Other):9    

In [ ]: